//******************************************************************
//******************************************************************
//**********          ANts Peer To Peer Sources        *************
//
// ANts P2P realizes a third generation P2P net. It protects your
// privacy while you are connected and makes you not trackable, hiding
// your identity (ip) and crypting everything you are sending/receiving
// from others.

// Copyright (C) 2004  Roberto Rossi

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package ants.p2p.filesharing;

import java.io.*;

import ants.p2p.utils.indexer.*;

import org.apache.log4j.*;

import kerjodando.casper.util.StringUtil;

public class InterruptedDownload {
	String fileName;

	String fileHash;

	String ed2kFileHash;

	Object[] chunkHashes;

	String extendedInfos;

	long assignedCoprime;

	long byteDownloaded;

	long fileSize;

	int blockSize;

	boolean[] downloadedBlockGroups;

	AutoresumeEngine ae;

	static Logger _logger = Logger.getLogger(InterruptedDownload.class
			.getName());

	public InterruptedDownload(MultipleSourcesDownloadManager store) {
		this.fileName = store.getFileName();
		this.fileHash = store.getFileHash();
		this.ed2kFileHash = store.getED2KFileHash();
		this.chunkHashes = store.chunkHashes;
		this.byteDownloaded = store.getByteDownloaded();
		this.fileSize = store.getFileSize();
		this.blockSize = store.getBlockSize();
		this.extendedInfos = store.getExtendedInfos();
		this.assignedCoprime = store.assignedCoprime;
		downloadedBlockGroups = store.getDownloadedBlockGroups();
		if (this.chunkHashes != null)
			BackgroundEngine.getInstance().addPartialFile(this);
	}

	public boolean[] getDownloadedBlockGroups() {
		return this.downloadedBlockGroups;
	}

	public InterruptedDownload(File store) throws Exception {
		ObjectInputStream ois = null;
		try {
			this.fileName = store.getName();
			if (store.exists()) {
				ois = new ObjectInputStream(new FileInputStream(store));
				this.downloadedBlockGroups = (boolean[]) ois.readObject();
				this.fileName = (String) ois.readObject();
				this.fileHash = (String) ois.readObject();
				this.ed2kFileHash = (String) ois.readObject();
				this.chunkHashes = (Object[]) ois.readObject();
				this.byteDownloaded = ((Long) ois.readObject()).longValue();
				this.fileSize = ((Long) ois.readObject()).longValue();
				this.blockSize = ((Integer) ois.readObject()).intValue();
				this.assignedCoprime = ((Long) ois.readObject()).longValue();
				this.extendedInfos = (String) ois.readObject();
				ois.close();
				if (this.blockSize != WarriorAnt.blockSizeInDownload) {
					throw new Exception(
							"Failed loading InterruptedDownload .mul file: incompatible blocksize "
									+ this.fileName);
				}
				BackgroundEngine.getInstance().addPartialFile(this);
			} else {
				throw new Exception(
						"Failed loading InterruptedDownload .mul file: fiile not found "
								+ this.fileName);
			}
		} catch (Exception e) {
			ois.close();
			_logger.error("Failed loading InterruptedDownload .mul file: "
					+ store.getName() + " chuncks preserved!", e);
			throw new Exception(
					"Failed loading InterruptedDownload .mul file: "
							+ store.getName() + " chuncks preserved!", e);
		}
	}

	public int getAvaiablePreviewIndexes() {
		int x = 0;
		while (this.downloadedBlockGroups[x]) {
			x++;
		}
		return x;
	}

	public int getIntPercentage() {
		int den = this.downloadedBlockGroups.length;
		int num = 0;
		for (int x = 0; x < this.downloadedBlockGroups.length; x++)
			if (this.downloadedBlockGroups[x] == true)
				num++;
		double perc = (num * 1.0 / den) * 100;
		return (int) perc;
	}

	public String getPercentage() {
		return (int) getIntPercentage() + "%";
	}

	public int getBlockSize() {
		return this.blockSize;
	}

	public String getFileHash() {
		return this.fileHash;
	}

	public String getED2KFileHash() {
		return this.ed2kFileHash;
	}

	public Object[] getChunkHashes() {
		return this.chunkHashes;
	}

	public String getFileName() {
		return this.fileName;
	}

	public String getExtendedInfos() {
		return this.extendedInfos;
	}

	public long getFileSize() {
		return this.fileSize;
	}

	public long getByteDownloaded() {
		return this.byteDownloaded;
	}

	public void removeInterrupted() {
		for (int x = 0; x < this.getDownloadedBlockGroups().length; x++) {
			if (this.getDownloadedBlockGroups()[x] == true) {
				try {
					File f = new File(WarriorAnt.chunksHome
							+ WarriorAnt.chunksPath + this.getFileHash() + "."
							+ x);
					f.delete();
				} catch (Exception ex) {
				}
			}
		}
		try {
			File f = new File(WarriorAnt.chunksHome + WarriorAnt.chunksPath
					+ this.getFileHash() + ".mul");
			f.delete();
		} catch (Exception ex) {
		}
		BackgroundEngine.getInstance().removePartialFile(this.getFileHash());
	}

	public String toString() {
		String result = this.getPercentage();
		while (result.length() < 8)
			result += " ";
		result += " " + StringUtil.fileSize2Str(this.getFileSize()) + " ";
		while (result.length() < 25)
			result += " ";
		result += " " + this.getFileHash() + " ";
		result += "     ";
		result += this.getFileName();
		return result;
	}

	public void addAutoresumeEngine(AutoresumeEngine ae) {
		if (this.ae != null && !this.ae.deactivated())
			this.ae.deactivate();
		this.ae = ae;
		if (this.ae != null && !this.ae.isAlive()) {
			this.ae.start();
			while (!this.ae.isAlive()) {
				try {
					Thread.currentThread().sleep(1000); // .yield()
				} catch (InterruptedException ex) {
				}
			}
		}
	}

	public AutoresumeEngine getAutoresumeEngine() {
		return this.ae;
	}

	public void deactivateAutoresumeEngine() {
		if (this.ae != null && !this.ae.deactivated()) {
			this.ae.deactivate();
			this.ae = null;
		}
	}

	public boolean isAutoresumeActive() {
		if (this.ae != null && !this.ae.deactivated())
			return true;
		else
			return false;
	}
}
